package com.bilibili.server.service;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.bilibili.autoconfig.template.HuanXinTemplate;
import com.bilibili.commons.Constants;
import com.bilibili.commons.exception.TanHuaException;
import com.bilibili.dubbo.api.mongo.UserLikeApi;
import com.bilibili.dubbo.api.db.QuestionApi;
import com.bilibili.dubbo.api.db.UserInfoApi;
import com.bilibili.dubbo.api.mongo.RecommendUserApi;
import com.bilibili.dubbo.api.mongo.UserLocationApi;
import com.bilibili.dubbo.api.mongo.VisitorsApi;
import com.bilibili.model.db.UserInfo;
import com.bilibili.model.mongo.RecommendUser;
import com.bilibili.model.mongo.UserLike;
import com.bilibili.model.mongo.UserLocation;
import com.bilibili.model.mongo.Visitors;
import com.bilibili.model.vo.*;
import com.bilibili.server.interceptor.UserHolder;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author HuangRongFu
 * 2021/11/19 星期五8:36 下午
 */

@Service
public class TanhuaService {

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    //指定默认数据
    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    /**
     * 每日佳人 推荐
     *
     * @Return: TodayBest
     */
    public TodayBest todayBest() {

        //查询每日佳人 通过登录用户id查询
        Long loginUserId = UserHolder.getUserId();

        //通过用户id  调用api查询 出来的分数最高的用户信息
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(loginUserId);

        //如果为空 则返回一个客服
        if (recommendUser == null) {

            recommendUser = new RecommendUser();

            //获取到客服机器人的id
            long serviceUserId = loginUserId % 99 + 1;

            recommendUser.setScore(88d);
            recommendUser.setUserId(serviceUserId);
        }
        //不为空 则查询佳人信息
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());

        //创建vo 设置属性  init中 见userInfo信息复制给了 todayBeat  缘分值 从recommendUser中获取 set
        TodayBest todayBest = TodayBest.init(userInfo, recommendUser);

        //返回
        return todayBest;
    }

    /**
     * 每日推荐
     *
     * @param: queryParam
     * @Return: PageResult
     */
    public PageResult<TodayBest> recommendation(RecommendUserQueryParam queryParam) {

        //1 分页查询每日推荐好友  通过登录用户id查询 这个是去mongoDB中查询
        // 已解决 理解
        PageResult pageResult = recommendUserApi.findPage(UserHolder.getUserId(), queryParam.getPage(),
                queryParam.getPagesize());

        //2 获取每日推荐好友id
        List<RecommendUser> recommendUserList = pageResult.getItems();
        ArrayList<TodayBest> voList = new ArrayList<>();

        //如果第一页没有数据就补充客服数据
        if (queryParam.getPage() == 1 && CollectionUtils.isEmpty(recommendUserList)) {

            recommendUserList = getDefaultRecommendUserList();// 获取默认的客服
            pageResult.setCounts(10l);
            pageResult.setPage(1l);
            pageResult.setPages(1l);
        }

        //只有获取的好友集合不为空是 才去查询推荐好友id集合
        if (CollectionUtils.isNotEmpty(recommendUserList)) {

            //获取好友id集合
            List<Long> userIds = recommendUserList.stream().map(RecommendUser::getUserId).collect(Collectors.toList());

            //3 查询好友详细信息
            //3.1 构建查询条件 pojo
            UserInfo userInfoCondition = new UserInfo();

            userInfoCondition.setAge(queryParam.getAge());
            userInfoCondition.setGender(queryParam.getGender());

            Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds, userInfoCondition);
            //4 装成TodayBest
            for (RecommendUser recommendUser : recommendUserList) {

                //获取佳人信息
                UserInfo userInfo = userInfoMap.get(recommendUser.getUserId());

                //佳人信息不为空加入到集合中
                if (userInfo != null) {

                    voList.add(TodayBest.init(userInfo, recommendUser));
                }
            }
        }
        //5 放回pageResult
        pageResult.setItems(voList);

        //6 返回pageResult
        return pageResult;
    }

    /**
     * 默认客服
     *
     * @return
     */
    private List<RecommendUser> getDefaultRecommendUserList() {
        List<RecommendUser> list = new ArrayList<>();
        // 随机产生开始的客户id, 从这个客服的id开始，往后取10个
        int startIndex = RandomUtils.nextInt(1, 90);
        RecommendUser recommendUser = null;
        for (long i = startIndex; i < startIndex + 10; i++) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(i);
            recommendUser.setScore(RandomUtils.nextDouble(70, 88));
            list.add(recommendUser);
        }
        return list;
    }

    /**
     * 佳人信息
     *
     * @param: id
     * @Return: ResponseEntity
     */
    public TodayBest findPersonalInfo(Long userId) {

        UserInfo userInfo = userInfoApi.findById(userId);

        RecommendUser recommendUser = recommendUserApi.queryByUserId(userId, UserHolder.getUserId());

        long timeMillis = System.currentTimeMillis();

        Visitors visitors = new Visitors();

        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(timeMillis);
        visitors.setScore(recommendUser.getScore());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));

        visitorsApi.save(visitors);

        return TodayBest.init(userInfo, recommendUser);
    }

    /**
     * 查看陌生人消息
     *
     * @param: userId
     * @Return: ResponseEntity
     */
    public String strangerQuestions(Long userId) {

        String question = questionApi.findQuestionByUserId(userId);

        return question;
    }

    /**
     * 回复陌生人消息
     *
     * @param: userId
     * @Return: ResponseEntity
     */
    public void replyQuestions(Map<String, Object> paramMap) {

        //获取回复信息的用户id
        //查询用户信息
        UserInfo userInfo = userInfoApi.findById(UserHolder.getUserId());

        Long userId = ((Integer) paramMap.get("userId")).longValue();

        Map<String, Object> map = new HashMap();

        /*
        消息格式
        "userId": 106,
        "huanXinId": "hx106",
        "nickname": "黑马小妹",
        "strangerQuestion": "你喜欢去看蔚蓝的大海还是去爬巍峨的高山？",
        "reply": "我喜欢秋天的落叶，夏天的泉水，冬天的雪地，只要有你一切皆可~"
         */
        map.put("userId", UserHolder.getUserId());
        map.put("huanXinId", Constants.HX_USER_PREFIX + UserHolder.getUserId());
        map.put("nickname", userInfo.getNickname());
        map.put("strangerQuestion", strangerQuestions(userId));
        map.put("reply", paramMap.get("reply"));

        String message = JSON.toJSONString(map);
        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + paramMap.get("userId"), message);

        if (!aBoolean) {

            throw new TanHuaException(ErrorResult.error());
        }
    }

    /**
     * 推荐列表
     *
     * @Return: List
     */
    public List<TodayBest> queryCardsList() {

        Long loginUserId = UserHolder.getUserId();
        //去查user_like表  排除喜欢/不喜欢的用户 并且限定数量
        List<RecommendUser> recommendUserList = recommendUserApi.queryCardsList(loginUserId, 10);


        //判断数据是否存在, 不存在构造默认数据, 1, 2, 3
        if (CollectionUtils.isEmpty(recommendUserList)) {

            recommendUserList = new ArrayList<>();

            String[] userIds = recommendUser.split(",");

            for (String userId : userIds) {

                RecommendUser user = new RecommendUser();

                user.setUserId(Long.valueOf(userId));
                user.setToUserId(loginUserId);
                user.setScore(RandomUtil.randomDouble(60, 90));

                recommendUserList.add(user);
            }
        }

        //构造VO
        List<Long> ids = recommendUserList.stream().map(RecommendUser::getUserId).collect(Collectors.toList());

        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);

        List<TodayBest> voList = new ArrayList<>();

        for (RecommendUser user : recommendUserList) {

            UserInfo userInfo = infoMap.get(user.getUserId());

            if (userInfo != null) {

                TodayBest vo = TodayBest.init(userInfo, user);

                voList.add(vo);
            }
        }

        return voList;
    }

    /**
     * 左滑右滑
     *
     * @param userId
     * @param isLove
     * @Return: null
     */
    public void love(Long userId, boolean isLove) {

        //保存userLike表
        //构建pojo
        UserLike userLike = new UserLike();
        userLike.setUserId(UserHolder.getUserId());
        userLike.setIsLike(isLove);
        userLike.setLikeUserId(userId);

        //调用api保存
        Boolean isFriend = userLikeApi.save(userLike);

        //处理Redis set中的值
        String likeKey = Constants.USER_LIKE_KEY + userId;
        String unlikeKey = Constants.USER_NOT_LIKE_KEY + userId;

        //判断isLove true
        if (isLove) {
            //添加到喜欢的set数据
            stringRedisTemplate.opsForSet().add(likeKey, userId.toString());

            //移除不喜欢集合中的数据
            stringRedisTemplate.opsForSet().remove(unlikeKey, userId.toString());
        }else{
            //false
            //添加到不喜欢的set集合中
            stringRedisTemplate.opsForSet().add(unlikeKey, userId.toString());

            //移除喜欢集合中的数据
            stringRedisTemplate.opsForSet().remove(likeKey, userId.toString());
        }

        //判断是否需要在环信上注册为好友
        if (isFriend) {

            huanXinTemplate.addContact(Constants.HX_USER_PREFIX + UserHolder.getUserId(),
                    Constants.HX_USER_PREFIX + userId);
        }
    }

    /**
     * 查附近
     * @param gender
     * @param distance
     * @Return: List
     */
    public List<NearUserVo> searchNearBy(String gender, Long distance) {

        //获取附近的用户集合
        List<Long> userIds = userLocationApi.searchNearBy(UserHolder.getUserId(), distance);

        List<NearUserVo> voList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(userIds)){

            UserInfo userInfo = new UserInfo();
            userInfo.setGender(gender);

            Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds, userInfo);

            voList = userInfoMap.values().stream().map(u -> NearUserVo.init(u)).collect(Collectors.toList());
        }

        return voList;
    }
}
